# ============================================================================
# PCG求解器测试脚本
# 测试固定迭代PCG求解器性能
# 预期：50次迭代 ~750ms（比Cholesky 1122ms快33%）
# ============================================================================

wipe
puts "==========================================
"
puts "PCG求解器性能测试"
puts "==========================================\n"

model basic -ndm 2 -ndf 2

# 创建150x150网格模型（与Cholesky测试相同）
set nEleX 150
set nEleY 150
set dx 0.1
set dy 0.1

puts "创建测试模型: ${nEleX}x${nEleX} = [expr $nEleX*$nEleY] 单元"

# 创建节点
set nodeTag 1
for {set j 0} {$j <= $nEleY} {incr j} {
    for {set i 0} {$i <= $nEleX} {incr i} {
        node $nodeTag [expr $i * $dx] [expr $j * $dy]
        incr nodeTag
    }
}

puts "节点数: [expr ($nEleX+1)*($nEleY+1)]"

# 底部固定
for {set i 1} {$i <= [expr $nEleX + 1]} {incr i} {
    fix $i 1 1
}

# 材料（线弹性）
nDMaterial ElasticIsotropic 1 2.0e8 0.3

# 创建单元
set eleTag 1
for {set j 1} {$j <= $nEleY} {incr j} {
    for {set i 1} {$i <= $nEleX} {incr i} {
        set n1 [expr ($j-1)*($nEleX+1) + $i]
        set n2 [expr $n1 + 1]
        set n3 [expr $j*($nEleX+1) + $i + 1]
        set n4 [expr $n3 - 1]

        element quad $eleTag $n1 $n2 $n3 $n4 1.0 PlaneStrain 1
        incr eleTag
    }
}

puts "单元数: [expr $nEleX*$nEleY]"

# 顶部施加荷载
set topLoad -100.0
for {set i 1} {$i <= [expr $nEleX + 1]} {incr i} {
    set topNode [expr $nEleY * ($nEleX + 1) + $i]
    pattern Plain 1 Linear {
        load $topNode 0.0 $topLoad
    }
}

# ============================================================================
# GPU求解器设置 - 启用PCG
# ============================================================================

# 注意：需要在C++代码中添加Tcl命令接口来切换求解器
# 这里假设已添加命令：GPUSolverSetType <type>
# type: 0=CHOLESKY, 1=PCG

system GPUSolver

# 尝试调用求解器切换命令（如果已实现）
# GPUSolverSetType 1
# GPUSolverSetPCGIterations 50

puts "\n==========================================
"
puts "求解器配置:"
puts "  类型: PCG (固定迭代)"
puts "  迭代次数: 50"
puts "  预条件: Jacobi"
puts "==========================================\n"

# ============================================================================
# 静态分析
# ============================================================================

constraints Plain
numberer RCM
test NormDispIncr 1.0e-6 100 0
algorithm Newton
integrator LoadControl 0.05
analysis Static

puts "\n开始PCG求解测试 (20步)...\n"

set startTime [clock milliseconds]

for {set step 1} {$step <= 20} {incr step} {
    set stepStart [clock milliseconds]

    analyze 1

    set stepEnd [clock milliseconds]
    set stepTime [expr $stepEnd - $stepStart]

    puts "PCG步 $step: $stepTime ms"
}

set endTime [clock milliseconds]
set totalTime [expr $endTime - $startTime]
set avgTime [expr $totalTime / 20.0]

puts "\n==========================================
"
puts "PCG求解器测试结果"
puts "==========================================
"
puts "总时间: $totalTime ms"
puts "平均/步: [format "%.1f" $avgTime] ms"
puts ""
puts "预期性能:"
puts "  PCG: ~750ms/步 (50次迭代)"
puts "  Cholesky: ~1122ms/步"
puts "  理论加速: 1.5x"
puts "==========================================\n"

wipe
